package com.rybbaby.tss.core.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.rybbaby.tss.core.annotation.RequestLog;
import com.rybbaby.tss.core.utils.FileUploadUtil;
import com.rybbaby.tss.core.utils.FileUtils;
import com.rybbaby.tss.core.utils.SequenceUtil;
import com.rybbaby.tss.core.utils.StringUtils;
import com.rybbaby.tss.core.utils.pojo.Size;
import com.rybbaby.tss.core.utils.pojo.TreeFile;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.SystemUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.rybbaby.tss.core.annotation.validator.RegexpValidator;
import com.rybbaby.tss.core.bean.TempUploadFile;
import com.rybbaby.tss.core.utils.AjaxJsonResponse;

/**
 * @author 谢进伟
 * @description 文件上传控制器
 * @createDate 2016年11月15日 上午9:54:29
 */
@Controller
@RequestMapping(value = "fileUpload")
public class FileUploadController extends BaseController {
	
	/**
	 * @param request
	 *            请求对象
	 * @param groupName
	 *            分组名
	 * @param sizes
	 *            缩放尺寸(格式：宽度-高度,宽度-高度,宽度-高度....),如：500-300,400-300
	 * @param isImg
	 *            是否图片临时文件上传
	 * @param imgMaxWidth
	 *            图片文件允许的最大宽度
	 * @param imgMaxHeight
	 *            图片文件允许的最大高度
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "upload")
	@RequestLog(content = "上传临时文件")
	public String upload(MultipartHttpServletRequest request , @RequestParam(required = true) String groupName , @RegexpValidator(nullable = true , regexp = "((\\d+-\\d+),?)+") String sizes , @RequestParam(required = false , defaultValue = "true") Boolean isImg , @RequestParam(required = false) Double imgMaxWidth , @RequestParam(required = false) Double imgMaxHeight) {
		AjaxJsonResponse ajr = new AjaxJsonResponse();
		try {
			List<Size> sizeList = new ArrayList<Size>();
			if(StringUtils.isNotBlank(sizes)) {
				for(String sizeStr : sizes.split(",")) {
					Size size = new Size(Integer.parseInt(sizeStr.split("-")[0]) , Integer.parseInt(sizeStr.split("-")[1]));
					sizeList.add(size);
				}
			}
			TempUploadFile uploadFile = FileUploadUtil.uploadFile(request , getSession().getId() , groupName , sizeList , isImg , imgMaxWidth , imgMaxHeight);// 上传文件
			TempUploadFile tempUploadFiles = FileUploadUtil.getTempUploadFile(groupName , getSession().getId());// 临时文件分组中所有临时文件
			if(tempUploadFiles != null) {
				ajr.setData(tempUploadFiles);
				ajr.addExtendParam("nowUpdateFile" , uploadFile);// 当前上传成功的临时文件
				return ajr.jsonResponse(true);
			} else {
				ajr.setResCode(-1);
				ajr.setResMsg("文件上传失败,请稍后再试!");
				return ajr.jsonResponse(false);
			}
		} catch (Exception e) {
			ajr.setResCode(-1);
			ajr.setResMsg(e.getMessage() == null ? "上传过程中发生异常!" : e.getMessage());
			return ajr.jsonResponse(false);
		}
	}
	
	/**
	 * @param groupName
	 *            分组名
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "clearTempFile")
	@RequestLog(content = "清理上传的临时文件")
	public String clearTempFile(@RequestParam(required = false) String groupName , String fileId) {
		AjaxJsonResponse ajr = new AjaxJsonResponse();
		try {
			String sessionId = getSession().getId();
			if(StringUtils.isBlank(fileId)) {
				FileUploadUtil.clearTemUploadFile(groupName , sessionId);// 删除上传的临时文件
				FileUtils.deleteDirectory(getTempFilePrevDir());// 删除图片预览临时目录
			} else {
				FileUploadUtil.clearTemUploadFile(groupName , sessionId , fileId);// 删除指定缓存文件
			}
			ajr.setResMsg("临时文件清理成功!");
			return ajr.jsonResponse(false);
		} catch (Exception e) {
			ajr.setResCode(-1);
			ajr.setResMsg((e.getMessage() == null ? "上传过程中发生异常!" : e.getMessage()));
			return ajr.jsonResponse(false);
		}
	}
	
	/**
	 * @param groupName
	 *            分组名
	 * @param fileId
	 *            文件Id
	 * @param response
	 */
	@ResponseBody
	@RequestMapping(value = "previewUploadImg" , method = RequestMethod.GET)
	@RequestLog(content = "预览上传的临时图片")
	public void preview(@RequestParam(required = true) String groupName , @RequestParam(required = true) String fileId , HttpServletResponse response) {
		try {
			if(StringUtils.isNotBlank(groupName)) {
				TempUploadFile tempUploadFile = FileUploadUtil.getTempUploadFile(groupName , getSession().getId());
				if(tempUploadFile != null) {
					List<TreeFile> fileList = tempUploadFile.getFileList();
					if(fileList != null && !fileList.isEmpty()) {
						for(TreeFile tf : fileList) {
							if(tf.getUuid().equals(fileId)) {
								FileInputStream inputStream = new FileInputStream(tf.getPath());
								ServletOutputStream outputStream = response.getOutputStream();
								IOUtils.copy(inputStream , outputStream);// 输出预览文件
								IOUtils.closeQuietly(inputStream);
								IOUtils.closeQuietly(outputStream);
							}
						}
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @param fileName
	 *            预览文件名称
	 * @param response
	 */
	@ResponseBody
	@RequestMapping(value = "preview" , method = RequestMethod.GET)
	@RequestLog(content = "预览解码后的额临时图片")
	public void preview(@RequestParam(required = true) String fileName , HttpServletResponse response) {
		try {
			File tempDirectory = getTempFilePrevDir();
			File [] listFiles = tempDirectory.listFiles(new FilenameFilter() {
				
				@Override
				public boolean accept(File dir , String name) {
					return name.equals(fileName);
				}
			});
			if(listFiles != null && listFiles.length > 0) {
				File tempPrevFile = listFiles[0];// 临时预览文件
				FileInputStream inputStream = new FileInputStream(tempPrevFile);
				ServletOutputStream outputStream = response.getOutputStream();
				IOUtils.copy(inputStream , outputStream);// 输出预览文件
				IOUtils.closeQuietly(inputStream);
				IOUtils.closeQuietly(outputStream);
				boolean delete = tempPrevFile.delete();
				if(delete) {
					info("成功删除临时预览文件" + tempPrevFile.getPath());
				} else {
					info("删除临时预览文件失败!");
					tempPrevFile.deleteOnExit();// 标记文件为程序退出自动删除
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@ResponseBody
	@RequestLog(content = "图片解码")
	@SuppressWarnings("restriction")
	@RequestMapping(value = "decode" , method = RequestMethod.POST)
	public String decode(HttpServletResponse response) {
		AjaxJsonResponse ajr = new AjaxJsonResponse();
		try {
			String data = IOUtils.toString(getRequest().getInputStream());
			if(StringUtils.isNotBlank(data)) {
				String [] split = data.split(",");
				String type = split[0].split(";")[0].split(":")[1];
				if(StringUtils.startsWith(type , "image")) {
					sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
					String imgData = split[1];
					byte [] decode = decoder.decodeBuffer(imgData);
					File tempDirectory = getTempFilePrevDir();
					if(!tempDirectory.exists()) {
						tempDirectory.mkdirs();
					}
					File f = File.createTempFile("prev_" + SequenceUtil.getLowerCaseUUID() , ".jpg" , tempDirectory);
					FileOutputStream outputStream = new FileOutputStream(f);
					IOUtils.write(decode , outputStream);
					IOUtils.closeQuietly(outputStream);
					ajr.addExtendParam("fileName" , f.getName());
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return ajr.jsonResponse(false);
	}
	
	/**
	 * @return 临时文件预览目录
	 */
	private File getTempFilePrevDir() {
		return new File(SystemUtils.getJavaIoTmpDir().getPath() + File.pathSeparator + "prevImgs" + File.separator + getSession().getId());// 图片预览临时目录
	}
}
